﻿using System;
using System.Collections.Generic;
using System.Text;

namespace CentrifugalSealCalc
{
    public class Calc
    {
        public double SpecificGravity = 1.3;     // user input e.g. 1.3
       
        public Outputs Outputs { get; set; }

        public Impeller Impeller { get; set; }

        public Expeller Expeller { get; set; }

        public double Pinlet = 30000;           // user input e.g. 30000 Pa

        public Calc(Impeller impeller, Expeller expeller)
        {
            this.Impeller = impeller;
            this.Expeller = expeller;
        }

        public Outputs Start()
        {
            Outputs = new Outputs();

            Impeller.K = GetK(Impeller.T, Impeller.C);
            Expeller.K = GetK(Expeller.T, Expeller.C);

            // Result.Pinlet = SpecificGravity * SuctionHead * 9.8605 * 1000;

            Pinlet = Global.InletGPressure * 1000;

            Outputs.SuctionHead = Global.InletGPressure / (SpecificGravity * 9.8605);
            
            
            Outputs.Pc = GetPressureCasing(Pinlet);
            //Outputs.PdropImp = GetPdropImp;

            Outputs.PdropImp = GetPdropImp(Impeller.Ns);
            Outputs.PdropExp = GetPdropExp(Expeller.Ns);


            Outputs.Phub = Outputs.Pc - Outputs.PdropImp;
            Outputs.Pgland = Outputs.Phub - Outputs.PdropExp;

            Outputs.Pmax = Outputs.PdropExp + Outputs.PdropImp - Outputs.Pc + Pinlet;
            double Pc_max = GetPressureCasing(Outputs.Pmax);
            Outputs.Nd = Math.Sqrt(Outputs.Pc / (GetPdropExp(1) + GetPdropImp(1)));

            Outputs.dr = Impeller.Ns / Outputs.Nd * Impeller.Ds;
            Outputs.percReduction = Outputs.dr / Impeller.Ds * 100; // RoundUp(_outputs.dr / _impeller.Ds * 100, 5);

            string diCode = string.Empty;
            int percReduction = (int)Round(Outputs.percReduction, 5);
            switch (percReduction)
            {
                case 95:
                    diCode = "B";
                    break;
                case 90:
                    diCode = "D";
                    break;
                case 85:
                    diCode = "F";
                    break;
                case 80:
                    diCode = "H";
                    break;
                case 75:
                    diCode = "J";
                    break;
                case 70:
                    diCode = "L";
                    break;
            }

            Outputs.MessageImepellerCode = string.Format("Use a Type {0} impeller.", diCode);
            Outputs.Safe = Outputs.Pgland < 0;
            Outputs.Message = Outputs.Safe ? "Seal should not leak." : "Seal is leaking.";

            return Outputs;
        }

        public static int Round(double i, int x)  
        {
            return (int)(Math.Floor(i / (double)x) * x);  //floor , ceiling, round
        }

        public double GetPressureCasing(double pressure)
        {
            return pressure + Impeller.A1 - Impeller.A2 * Math.Pow(Impeller.Q, Impeller.A3);
        }

        public double GetPdropImp(double speed)
        {
            return 5.48 * Math.Pow(Impeller.K, 2) * Math.Pow(speed, 2) * (Math.Pow(Impeller.R2, 2) - Math.Pow(Impeller.R1, 2));
        }

        public double GetPdropExp(double speed)
        {
            return 5.48 * Math.Pow(Expeller.K, 2) * Math.Pow(speed, 2) * (Math.Pow(Expeller.R2, 2) - Math.Pow(Expeller.R1, 2));
        }

        public double GetK(double T, double C)
        {
            return 0.7 + 0.3 * (T / (T + C));
        }
    }
}